package com.lottery.material.service.portal.user.impl;

import com.lottery.material.common.Constants;
import com.lottery.material.dao.article.ArticleActiveInfoMapper;
import com.lottery.material.dao.article.ArticleInfoMapper;
import com.lottery.material.dao.circle.CircleMemberInfoMapper;
import com.lottery.material.dao.conf.PlatformScaleConfigMapper;
import com.lottery.material.dao.conf.SystemParameterConfigMapper;
import com.lottery.material.dao.interfaces.InterfaceAccessHistoryMapper;
import com.lottery.material.dao.portaluser.BuyGoldConfigMapper;
import com.lottery.material.dao.portaluser.FollowInfoMapper;
import com.lottery.material.dao.portaluser.PortalUserInfoMapper;
import com.lottery.material.dao.portaluser.ValidateCodeRecordMapper;
import com.lottery.material.dao.promotion.PromotionRealtimeRecordMapper;
import com.lottery.material.dao.promotion.PromotionRuleConfigMapper;
import com.lottery.material.dao.transaction.TransactionRecordMapper;
import com.lottery.material.dao.transaction.TransactionTypeDictMapper;
import com.lottery.material.dao.transaction.UserEarnRecordMapper;
import com.lottery.material.enumeration.ResultEnum;
import com.lottery.material.jedis.JedisClient;
import com.lottery.material.pojo.article.ArticleInfo;
import com.lottery.material.pojo.circle.CircleMemberInfo;
import com.lottery.material.pojo.conf.PlatformScaleConfig;
import com.lottery.material.pojo.conf.SystemParameterConfig;
import com.lottery.material.pojo.interfaces.InterfaceAccessHistory;
import com.lottery.material.pojo.portaluser.FollowInfo;
import com.lottery.material.pojo.portaluser.PortalUserInfo;
import com.lottery.material.pojo.portaluser.ValidateCodeRecord;
import com.lottery.material.pojo.promotion.PromotionRealtimeRecord;
import com.lottery.material.pojo.promotion.PromotionRuleConfig;
import com.lottery.material.pojo.transaction.TransactionRecord;
import com.lottery.material.pojo.transaction.UserEarnRecord;
import com.lottery.material.resolver.CustomException;
import com.lottery.material.service.portal.user.PortalUserInfoService;
import com.lottery.material.util.*;
import com.lottery.material.vo.portal.article.ArticleUserVo;
import com.lottery.material.vo.portal.transaction.EarnRecordStatisticsVo;
import com.lottery.material.vo.portal.user.AccountAndSecurityVo;
import com.lottery.material.vo.portal.user.AuthenticationUserVo;
import com.lottery.material.vo.portal.user.FollowUserVo;
import com.lottery.material.vo.portal.user.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;
import java.math.BigDecimal;


@Service
@Slf4j
public class PortalUserInfoServiceImpl implements PortalUserInfoService {
    @Autowired
    @Qualifier("jedisClientCluster")
    private JedisClient jedisClient;

    @Autowired
    PortalUserInfoMapper portalUserInfoMapper;
    @Autowired
    private TransactionRecordMapper transactionRecordMapper;
    @Autowired
    private ArticleInfoMapper articleInfoMapper;
    @Autowired
    private ArticleActiveInfoMapper articleActiveInfoMapper;
    @Autowired
    private PlatformScaleConfigMapper platformScaleConfigMapper;
    @Autowired
    private UserEarnRecordMapper userEarnRecordMapper;

    @Autowired
    private TransactionTypeDictMapper transactionTypeDictMapper;
    @Autowired
    private PromotionRealtimeRecordMapper promotionRealtimeRecordMapper;
    @Autowired
    private PromotionRuleConfigMapper promotionRuleConfigMapper;
    @Autowired
    private SystemParameterConfigMapper systemParameterConfigMapper;
    @Autowired
    private CircleMemberInfoMapper circleMemberInfoMapper;
    @Autowired
    private BuyGoldConfigMapper buyGoldConfigMapper;
    @Autowired
    private ValidateCodeRecordMapper validateCodeRecordMapper;
    @Autowired
    private InterfaceAccessHistoryMapper interfaceAccessHistoryMapper;
    @Autowired
    private FollowInfoMapper followInfoMapper;

    @Value("${tigase.server.host}")
    private String serverHost;
    @Value("${tigase.server.port}")
    private Integer serverPort;

    @Override
    public EarnRecordStatisticsVo findIncomeStatisticsByUserId(String userId) {
        return portalUserInfoMapper.findIncomeStatisticsByUserId(userId);
    }

    /**
     * 账户与安全
     *
     * @param userId
     * @return
     * @Author 焦阳
     */
    @Override
    public AccountAndSecurityVo findAccountAndSecurity(String userId) {
        return portalUserInfoMapper.findAccountAndSecurity(userId);
    }

    @Override
    public ResponseResult confirmAuthentication(String userId) {
        PortalUserInfo userInfo = portalUserInfoMapper.findByUserId(userId);
        if (userInfo.getUserType() == 2) {
            return ResponseResult.buildResult(ResultEnum.ALREADY_AUTH_USER_FAIL);
        } else {
            AuthenticationUserVo userVo = findUserAuthentication(userId);
            if ("2".equals(userVo.getIsAchieve())) {
                userInfo.setUserType(2);
                portalUserInfoMapper.updateByPrimaryKeySelective(userInfo);
                return ResponseResult.buildResult(ResultEnum.USER_AUTH_SUCCESS);
            } else {
                return ResponseResult.buildResult(ResultEnum.AUTHENTICATION_NOT_ACHIEVE);
            }
        }
    }

    /**
     * 常规认证检查
     *
     * @param userId
     * @return
     */
    @Override
    public AuthenticationUserVo findUserAuthentication(String userId) {
        AuthenticationUserVo userVo = portalUserInfoMapper.findUserAuthentication(userId);
        userVo.setIsAchieve("1");
        //验证实名，银行卡
        if ("2".equals(userVo.getIsRealNameAuth()) && "2".equals(userVo.getIsBindBankCard())) {
            //验证文章发表数
            if (Integer.parseInt(userVo.getPublishTotal()) > Integer.parseInt(userVo.getNeedPublishTotal())) {
                //验证粉丝数
                if (Integer.parseInt(userVo.getFansTotal()) > Integer.parseInt(userVo.getNeedFansTotal())) {
                    userVo.setIsAchieve("2");
                }
            }
        }
        return userVo;
    }

    /**
     * 前往充值
     *
     * @param userId
     * @return
     */
    @Override
    public Map<String, Object> findRechargeList(String userId) {
        Map<String, Object> resultMap = portalUserInfoMapper.findRemainGold(userId);
        List<Object> rechargeList = buyGoldConfigMapper.findRechargeList();
        resultMap.put("buyGolds", rechargeList);
        return resultMap;
    }

    /**
     * 查看我的财富
     *
     * @param userId
     * @return
     * @Author 焦阳
     */
    @Override
    public Map<String, Object> findMyTreasure(String userId) {
        return portalUserInfoMapper.findMyTreasure(userId);
    }

    /**
     * 查询关注列表
     *
     * @param userId
     * @return
     * @Author 焦阳
     */
    @Override
    public List<FollowUserVo> findFollowUserListByUserId(String userId, Integer page) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("indexStart", Const.PORTAL_PAGE * (page - 1));
        paramMap.put("pageTotal", Const.PORTAL_PAGE);
        paramMap.put("userId", userId);
        return portalUserInfoMapper.findFollowUserListByUserId(paramMap);
    }

    /**
     * 关注达人和圈子
     *
     * @param userIds
     * @param circleIds
     * @param userId
     * @return
     * @Author 焦阳
     */

    @Override
    public ResponseResult editWatchRxpertAndCircle(String userIds, String circleIds, String userId) {
        String[] masters = StringUtil.string2Array(userIds);
        String[] circles = StringUtil.string2Array(circleIds);
        Integer countMaster = 0;
        Integer countCirle = 0;
        //更新关注信息
        for (int i = 0; i < masters.length; i++) {
            String master = masters[i];
            FollowInfo followInfo = new FollowInfo();
            followInfo.setUserId(userId);
            followInfo.setFollowUserId(master);
            followInfo.setCreateTime(new Date());
            Integer i1 = followInfoMapper.insertSelective(followInfo);
            Integer i2 = portalUserInfoMapper.updateFollowTotal(master, "2");
            if (i1 == 1 && i2 == 1) {
                countMaster++;
            }
        }
        //更新圈子成员信息
        for (int i = 0; i < circles.length; i++) {
            String circle = circles[i];
            CircleMemberInfo circleMemberInfo = new CircleMemberInfo();
            circleMemberInfo.setIsTop(1);
            circleMemberInfo.setCircleId(Integer.valueOf(circle));
            circleMemberInfo.setRank(1);
            circleMemberInfo.setUserId(userId);
            circleMemberInfo.setIsBan(1);
            circleMemberInfo.setCreateTime(new Date());
            Integer i3 = circleMemberInfoMapper.insertSelective(circleMemberInfo);
            if (i3 == 1) {
                countCirle++;
            }
        }
        if (countMaster == masters.length && countCirle == circles.length) {
            return ResponseResult.buildResult(ResultEnum.FOLLOW_SUCCESS);
        } else {
            return ResponseResult.buildResult(ResultEnum.FOLLOW_FAIL);
        }
    }

    /**
     * 发送验证码
     *
     * @param map
     * @return
     * @Author 焦阳
     */
    @Override
    public ResponseResult sendVerificationCode(Map<String, String> map) throws IOException {
        // Post请求的url，与get不同的是不需要带参数
        URL postUrl = new URL(Const.MESSAGE_POST_URL);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
        // Output to the connection. Default is
        // false, set to true because post
        // method must write something to the
        // connection
        // 设置是否向connection输出，因为这个是post请求，参数要放在
        // http正文内，因此需要设为true
        connection.setDoOutput(true);
        // Read from the connection. Default is true.
        connection.setDoInput(true);
        // Set the post method. Default is GET
        connection.setRequestMethod("POST");
        // Post cannot use caches
        // Post 请求不能使用缓存
        connection.setUseCaches(false);
        // This method takes effects to
        // every instances of this class.
        // URLConnection.setFollowRedirects是static函数，作用于所有的URLConnection对象。
        // connection.setFollowRedirects(true);

        // This methods only
        // takes effacts to this
        // instance.
        // URLConnection.setInstanceFollowRedirects是成员函数，仅作用于当前函数
        connection.setInstanceFollowRedirects(true);
        // Set the content type to urlencoded,
        // because we will write
        // some URL-encoded content to the
        // connection. Settings above must be set before connect!
        // 配置本次连接的Content-type，配置为application/x-www-form-urlencoded的
        // 意思是正文是urlencoded编码过的form参数，下面我们可以看到我们对正文内容使用URLEncoder.encode
        // 进行编码
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        // 连接，从postUrl.openConnection()至此的配置必须要在connect之前完成，
        // 要注意的是connection.getOutputStream会隐含的进行connect。
        connection.connect();
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        // The URL-encoded contend
        String validCode = RandomUtil.getRandomNum(6);
        //下面为http发送短信模式--------
        String phoneNumber = map.get("phoneNumber");
        long start = System.currentTimeMillis();
        String content = "account=" + Const.MESSAGE_ACCOUNT + "&" + "password=" + Const.MESSAGE_PASSWORD + "&" + "sendDateTime=" + "" + "&" + "destmobile=" + phoneNumber + "&"
                + "msgText=" + URLEncoder.encode(String.format("尊敬的用户，您的验证码为：%s，该验证码5分钟内有效【掌上球事】", validCode), "UTF-8");

        log.info(content);
        out.writeBytes(content);

        out.flush();
        out.close(); // flush and close
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line;
        String sendResult = "0";
        log.info("=============================");
        long end = System.currentTimeMillis();
        while ((line = reader.readLine()) != null) {
            log.info("短信发送返回结果：" + line);
            sendResult = line;
        }
        log.info("=============================");
        reader.close();
        connection.disconnect();
        if (Long.parseLong(sendResult) <= 0) {
            return ResponseResult.buildResult(ResultEnum.SEND_MESSAGE_FAIL);
        } else {
            insertValidateCode(map, validCode, phoneNumber);
            insertInterfaceAccessHistory(start, content, sendResult, end);
            return ResponseResult.buildResult(ResultEnum.SEND_MESSAGE_SUCCESS);
        }
    }

    private void insertInterfaceAccessHistory(long start, String content, String line, long end) {
        InterfaceAccessHistory history = new InterfaceAccessHistory();
        history.setInterfaceName(Const.MESSAGE_POST_URL);
        history.setCreateTime(new Date());
        history.setProvider(Const.MESSAGE_PROVIDER);
        history.setRequestBody(content);
        history.setRequestHeader("Content-Type:application/x-www-form-urlencoded");
        history.setRequestMode("POST");
        history.setRequestUrl(Const.MESSAGE_POST_URL);
        history.setResponseResult(line);
        history.setResponseTime(String.valueOf(end - start));
        interfaceAccessHistoryMapper.insert(history);
    }

    private void insertValidateCode(Map<String, String> map, String validCode, String phoneNumber) {
        ValidateCodeRecord record = new ValidateCodeRecord();
        record.setPhoneNumber(phoneNumber);
        record.setValidateCode(validCode);
        record.setFailureTime(new Date(new Date().getTime() + 300000));
        record.setCreateTime(new Date());
        record.setSendSource(Integer.parseInt(map.get("sendSource")));
        validateCodeRecordMapper.insert(record);
    }

    /**
     * 查询粉丝列表
     *
     * @param userId
     * @return
     * @Author 焦阳
     */
    @Override
    public List<FollowUserVo> findFansUserListByUserId(String userId, Integer page) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("indexStart", Const.PORTAL_PAGE * (page - 1));
        paramMap.put("pageTotal", Const.PORTAL_PAGE);
        paramMap.put("userId", userId);
        return portalUserInfoMapper.findFansUserListByUserId(paramMap);
    }

    @Override
    public Integer updateByPrimaryKeySelective(PortalUserInfo record) {
        return portalUserInfoMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public PortalUserInfo findById(Integer id) {
        return portalUserInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public void insertSelective(PortalUserInfo portalUserInfo) {
        portalUserInfoMapper.insertSelective(portalUserInfo);
    }

    @Override
    public PortalUserInfo findByLoginPhoneNumberAndUserStatusNot(String phoneNumber, Integer userStatus) {
        return portalUserInfoMapper.findByLoginPhoneNumberAndUserStatusNot(phoneNumber, userStatus);
    }

    @Override
    public PortalUserInfo findByUserId(String userId) {
        return portalUserInfoMapper.findByUserId(userId);
    }

    @Override
    public UserVo findMyPortalUserInfoDtoByUserId(String userId) {
        return portalUserInfoMapper.findMyPortalUserInfoDtoByUserId(userId);
    }

    @Override
    public Map<String, Object> findPortalUserInfoDtoByUserId(String userId) {
        return portalUserInfoMapper.findPortalUserInfoDtoByUserId(userId);
    }

    @Override
    public ArticleUserVo findArticleUserVoByUserId(String userId) {
        return portalUserInfoMapper.findArticleUserVoByUserId(userId);
    }

    /**
     * description: 用户金币支付业务逻辑
     * author sunny
     * createDate 2019-04-17 下午 2:14
     *
     * @param portalUserInfo
     * @param reqParamMap
     * @return
     */
    @Override
    public ResponseResult insertUserGoldPayRecord(PortalUserInfo portalUserInfo, Map<String, String> reqParamMap) {
        String payAmount = reqParamMap.get("payAmount");
        if ("TLX00003".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00003:专家认证
            //封装交易数据
            TransactionRecord transactionRecord = new TransactionRecord();
            transactionRecord.setUserId(reqParamMap.get("userId"));
            transactionRecord.setTransactionTypeCode(reqParamMap.get("transactionTypeCode"));
            transactionRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
            transactionRecord.setOrderCode(IDUtil.createID());
            transactionRecord.setTransactionTitle(Constants.EXPERT_AUTH_TRADER_TITLE);
            transactionRecord.setAmount(Integer.valueOf(payAmount));
            transactionRecord.setUserBillType(2); //支出
            transactionRecord.setCompanyScale(new BigDecimal(1));
            transactionRecord.setCompanyEarnAmount(Integer.valueOf(payAmount));
            transactionRecord.setCompanyBillType(1); //收入
            if (!calculationGold(portalUserInfo.getUserId(), transactionRecord, new BigDecimal(payAmount))) {
                return ResponseResult.buildResult(ResultEnum.NOT_ENOUGH_GOLD_FAIL); //金币不足
            } else {
                //生成交易记录
                transactionRecordMapper.insertSelective(transactionRecord);
                return ResponseResult.buildResult(ResultEnum.EXPERT_AUTH_SUCCESS);
            }
        } else if ("TLX00004".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00004:圈员认证
            //封装交易数据
            TransactionRecord transactionRecord = new TransactionRecord();
            transactionRecord.setUserId(reqParamMap.get("userId"));
            transactionRecord.setTransactionTypeCode(reqParamMap.get("transactionTypeCode"));
            transactionRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
            transactionRecord.setOrderCode(IDUtil.createID());
            transactionRecord.setTransactionTitle(Constants.CIRCLE_AUTH_TRADER_TITLE);
            transactionRecord.setAmount(Integer.valueOf(payAmount));
            transactionRecord.setUserBillType(2); //支出
            transactionRecord.setCompanyScale(new BigDecimal(1));
            transactionRecord.setCompanyEarnAmount(Integer.valueOf(payAmount));
            transactionRecord.setCompanyBillType(1); //收入

            if (!calculationGold(portalUserInfo.getUserId(), transactionRecord, new BigDecimal(payAmount))) {
                return ResponseResult.buildResult(ResultEnum.NOT_ENOUGH_GOLD_FAIL); //金币不足
            } else {
                //生成交易记录
                transactionRecordMapper.insertSelective(transactionRecord);

                //更新圈子成员表
                CircleMemberInfo record = new CircleMemberInfo();
                record.setUserId(reqParamMap.get("userId"));
                record.setCircleId(Integer.valueOf(reqParamMap.get("circleId")));
                record.setRank(2);
                circleMemberInfoMapper.updateRankByUserIdAndCircleId(record);

                return ResponseResult.buildResult(ResultEnum.CIRCLE_AUTH_SUCCESS);
            }
        } else if ("TLX00005".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00005:查看收费文章
            //查看文章详细信息
            ArticleInfo articleInfo = articleInfoMapper.findByArticleId(reqParamMap.get("articleId"));
            if (Objects.isNull(articleInfo)) {
                return ResponseResult.buildResult(ResultEnum.ARTICLE_NOT_EXIST_FAIL);
            }

            //查看收费文章--系统平台收益分成比例
            PlatformScaleConfig platformScaleConfig = platformScaleConfigMapper.findByUtilityType(2);
            String userEarnAmount = MathUtil.mulHalfUp(payAmount, String.valueOf(platformScaleConfig.getAuthorScale()), 0);
            String companyEarnAmount = MathUtil.subHalfUp(payAmount, userEarnAmount, 0);

            //封装交易数据
            TransactionRecord transactionRecord = new TransactionRecord();
            transactionRecord.setUserId(reqParamMap.get("userId"));
            transactionRecord.setTransactionTypeCode(reqParamMap.get("transactionTypeCode"));
            transactionRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
            transactionRecord.setOrderCode(IDUtil.createID());
            transactionRecord.setTransactionTitle(String.format(Constants.VIEW_ARTICLE_TRADER_TITLE, articleInfo.getNickName()));
            transactionRecord.setAmount(Integer.valueOf(payAmount));
            transactionRecord.setUserBillType(2); //支出
            transactionRecord.setCompanyScale(platformScaleConfig.getPlatformScale());
            transactionRecord.setCompanyEarnAmount(Integer.valueOf(companyEarnAmount));
            transactionRecord.setCompanyBillType(1); //收入
            transactionRecord.setArticleId(reqParamMap.get("articleId"));

            if (!calculationGold(portalUserInfo.getUserId(), transactionRecord, new BigDecimal(payAmount))) {
                return ResponseResult.buildResult(ResultEnum.NOT_ENOUGH_GOLD_FAIL); //金币不足
            } else {
                //生成交易记录
                transactionRecordMapper.insertSelective(transactionRecord);

                //封装收益数据
                UserEarnRecord userEarnRecord = new UserEarnRecord();
                userEarnRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
                userEarnRecord.setOrderCode(IDUtil.genUniqueID());
                userEarnRecord.setUserId(articleInfo.getUserId());
                userEarnRecord.setEarnType(2); //查看文章收益
                userEarnRecord.setEarnTitle(String.format(Constants.VIEW_ARTICLE_EARN_TITLE, portalUserInfo.getNickName()));
                userEarnRecord.setUserEarnAmount(Integer.valueOf(userEarnAmount));
                userEarnRecord.setCompanyEarnAmount(Integer.valueOf(companyEarnAmount));
                userEarnRecord.setUserScale(platformScaleConfig.getAuthorScale());
                userEarnRecord.setCompanyScale(platformScaleConfig.getPlatformScale());
                userEarnRecord.setOriginalAmount(Integer.valueOf(payAmount));
                userEarnRecordMapper.insertSelective(userEarnRecord);
                return ResponseResult.buildResult(ResultEnum.VIEW_ARTICLE_SUCCESS);
            }
        } else if ("TLX00006".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00006:打赏文章
            //查看文章详细信息
            ArticleInfo articleInfo = articleInfoMapper.findByArticleId(reqParamMap.get("articleId"));
            if (Objects.isNull(articleInfo)) {
                return ResponseResult.buildResult(ResultEnum.ARTICLE_NOT_EXIST_FAIL);
            }

            //打赏文章--系统平台收益分成比例
            PlatformScaleConfig platformScaleConfig = platformScaleConfigMapper.findByUtilityType(1);
            String userEarnAmount = MathUtil.mulHalfUp(payAmount, String.valueOf(platformScaleConfig.getAuthorScale()), 0);
            String companyEarnAmount = MathUtil.subHalfUp(payAmount, userEarnAmount, 0);

            //封装交易数据
            TransactionRecord transactionRecord = new TransactionRecord();
            transactionRecord.setUserId(reqParamMap.get("userId"));
            transactionRecord.setTransactionTypeCode(reqParamMap.get("transactionTypeCode"));
            transactionRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
            transactionRecord.setOrderCode(IDUtil.createID());
            transactionRecord.setTransactionTitle(String.format(Constants.REWARD_ARTICLE_TRADER_TITLE, articleInfo.getNickName()));
            transactionRecord.setAmount(Integer.valueOf(payAmount));
            transactionRecord.setUserBillType(2); //支出
            transactionRecord.setCompanyScale(platformScaleConfig.getPlatformScale());
            transactionRecord.setCompanyEarnAmount(Integer.valueOf(companyEarnAmount));
            transactionRecord.setCompanyBillType(1); //收入
            transactionRecord.setArticleId(reqParamMap.get("articleId"));
            transactionRecord.setRewardReasonCode(reqParamMap.get("rewardReasonCode"));

            if (!calculationGold(portalUserInfo.getUserId(), transactionRecord, new BigDecimal(payAmount))) {
                return ResponseResult.buildResult(ResultEnum.NOT_ENOUGH_GOLD_FAIL); //金币不足
            } else {
                //生成交易记录
                transactionRecordMapper.insertSelective(transactionRecord);

                //封装收益数据
                UserEarnRecord userEarnRecord = new UserEarnRecord();
                userEarnRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
                userEarnRecord.setOrderCode(IDUtil.genUniqueID());
                userEarnRecord.setUserId(articleInfo.getUserId());
                userEarnRecord.setEarnType(1); //打赏文章收益
                userEarnRecord.setEarnTitle(String.format(Constants.REWARD_ARTICLE_EARN_TITLE, portalUserInfo.getNickName()));
                userEarnRecord.setUserEarnAmount(Integer.valueOf(userEarnAmount));
                userEarnRecord.setCompanyEarnAmount(Integer.valueOf(companyEarnAmount));
                userEarnRecord.setUserScale(platformScaleConfig.getAuthorScale());
                userEarnRecord.setCompanyScale(platformScaleConfig.getPlatformScale());
                userEarnRecord.setOriginalAmount(Integer.valueOf(payAmount));
                userEarnRecordMapper.insertSelective(userEarnRecord);
                return ResponseResult.buildResult(ResultEnum.REWARD_ARTICLE_SUCCESS);
            }
        } else if ("TLX00007".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00007:付费推广
            //查看文章详细信息
            ArticleInfo articleInfo = articleInfoMapper.findByArticleId(reqParamMap.get("articleId"));
            if (Objects.isNull(articleInfo)) {
                return ResponseResult.buildResult(ResultEnum.ARTICLE_NOT_EXIST_FAIL);
            }

            //文章被驳回
            if (articleInfo.getArticleState() == 2) {
                return ResponseResult.buildResult(ResultEnum.PROMOTION_PAY_REJECT_FAIL);
            }

            if (2 == articleInfo.getIsPromotion()) { //已经申请过推广
                return ResponseResult.buildResult(ResultEnum.APPLY_PROMOTION_FAIL);
            }

            //封装交易数据
            TransactionRecord transactionRecord = new TransactionRecord();
            transactionRecord.setUserId(reqParamMap.get("userId"));
            transactionRecord.setTransactionTypeCode(reqParamMap.get("transactionTypeCode"));
            transactionRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
            transactionRecord.setOrderCode(IDUtil.createID());
            transactionRecord.setTransactionTitle(Constants.PROMOTION_PAY_TRADER_TITLE);
            transactionRecord.setAmount(Integer.valueOf(payAmount));
            transactionRecord.setUserBillType(2); //支出
            transactionRecord.setCompanyScale(new BigDecimal(1));
            transactionRecord.setCompanyEarnAmount(Integer.valueOf(payAmount));
            transactionRecord.setCompanyBillType(1); //收入
            if (!calculationGold(portalUserInfo.getUserId(), transactionRecord, new BigDecimal(payAmount))) {
                return ResponseResult.buildResult(ResultEnum.NOT_ENOUGH_GOLD_FAIL); //金币不足
            } else {
                //生成交易记录
                transactionRecordMapper.insertSelective(transactionRecord);

                //获取圈子内文章推广规则配置信息
                PromotionRuleConfig promotionRuleConfig = promotionRuleConfigMapper.findByPromotionType(1);

                //生成推广记录
                PromotionRealtimeRecord promotionRealtimeRecord = new PromotionRealtimeRecord();
                promotionRealtimeRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
                promotionRealtimeRecord.setUserId(reqParamMap.get("userId"));
                promotionRealtimeRecord.setArticleId(articleInfo.getArticleId());
                promotionRealtimeRecord.setPromotionStartTime(CalendarUtil.getSystemCurrentDate());
                //计算推广结束时间
                Date promotionEndTime = CalendarUtil.getWantedDate(CalendarUtil.getSystemCurrentDate(), null, null, null, null, promotionRuleConfig.getPromotionDuration());
                promotionRealtimeRecord.setPromotionEndTime(promotionEndTime);
                promotionRealtimeRecordMapper.insertSelective(promotionRealtimeRecord);

                //更新文章信息
                Map<String, Object> paramMap = new HashMap<String, Object>();
                paramMap.put("articleId", articleInfo.getArticleId());
                paramMap.put("isPromotion", 2);
                paramMap.put("promotionAmount", payAmount);
                paramMap.put("promotionTime", CalendarUtil.getSystemCurrentDate());
                articleInfoMapper.updateArticlePromotion(paramMap);
                articleActiveInfoMapper.updateArticlePromotion(paramMap);

                if (articleInfo.getArticleState() == 3) {
                    return ResponseResult.buildResult(ResultEnum.PROMOTION_PAY_SUCCESS);
                } else {
                    return ResponseResult.buildResult(ResultEnum.PROMOTION_PAY_TO_AUDIT_SUCCESS);
                }
            }
        }
        return ResponseResult.buildResult(ResultEnum.PAYMENT_FAIL);
    }

    /**
     * description: 金币计算
     * author sunny
     * createDate 2019-04-17 下午 3:44
     *
     * @param userId
     * @param transactionRecord
     * @param payAmount
     * @return
     */
    private Boolean calculationGold(String userId, TransactionRecord transactionRecord, BigDecimal payAmount) {
        synchronized (this) {
            PortalUserInfo portalUserInfo = portalUserInfoMapper.findByUserId(userId);
            //充值--金币
            BigDecimal goldBuy = new BigDecimal(portalUserInfo.getGoldBuy());
            //收益--金币
            BigDecimal goldProfit = new BigDecimal(portalUserInfo.getGoldProfit());
            if (goldBuy.compareTo(payAmount) == -1) { //充值的剩余金币小于需要支付的金币
                //计算还需要支付的金币
                BigDecimal needPayGold = payAmount.subtract(goldBuy);
                if (goldProfit.compareTo(needPayGold) == -1) {
                    return false;
                }
                transactionRecord.setBuyPayAmount(goldBuy.intValue()); //设置充值部分支付金额
                goldBuy = new BigDecimal(0); //计算扣除后充值里金额
                transactionRecord.setProfitPayAmount(needPayGold.intValue()); //设置收益部分支付金额
                goldProfit = goldProfit.subtract(needPayGold); //计算扣除后收益里金额

                //封装收益金币消费记录
                String earnTitle = transactionTypeDictMapper.findByTransactionTypeCode(transactionRecord.getTransactionTypeCode());
                UserEarnRecord userEarnRecord = new UserEarnRecord();
                userEarnRecord.setCreateTime(CalendarUtil.getSystemCurrentDate());
                userEarnRecord.setOrderCode(IDUtil.genUniqueID());
                userEarnRecord.setUserId(portalUserInfo.getUserId());
                userEarnRecord.setEarnType(3); //收益金币消费
                userEarnRecord.setEarnTitle(earnTitle);
                userEarnRecord.setPayAmount(needPayGold.intValue());
                userEarnRecordMapper.insertSelective(userEarnRecord);
            } else {
                transactionRecord.setBuyPayAmount(payAmount.intValue()); //设置充值部分支付金额
                goldBuy = goldBuy.subtract(payAmount); //计算扣除后充值里金额
            }
            //更新个人帐户余额
            portalUserInfo.setGoldBuy(goldBuy.intValue());
            portalUserInfo.setGoldProfit(goldProfit.intValue());
            if ("TLX00003".equals(transactionRecord.getTransactionTypeCode())) {
                portalUserInfo.setUserType(2); //设置认证用户
            }
            portalUserInfoMapper.updateByPrimaryKeySelective(portalUserInfo);
            return true;
        }
    }

    /**
     * 注册用户
     *
     * @param phoneNumber
     * @param password
     * @return
     * @Author 焦阳
     */
    @Override
    public Map<String, String> addUser(String phoneNumber, String password, String channelCode) throws Exception {
        PortalUserInfo portalUserInfo = new PortalUserInfo();
        portalUserInfo.setLoginPhoneNumber(phoneNumber);
//        String salt = StringUtil.getRandomNumChar(8);
        portalUserInfo.setLoginPassword(MD5Util.MD5(password));
//        portalUserInfo.setSalt(salt);
        String userId = UUID.randomUUID().toString();
        portalUserInfo.setUserId(userId);
        String accessToken = UUID.randomUUID().toString();
        portalUserInfo.setAccessToken(accessToken);
        portalUserInfo.setUserStatus(1);
        portalUserInfo.setCreateTime(new Date());
        portalUserInfo.setUserType(1);
        portalUserInfo.setUserLevel(1);
        portalUserInfo.setChannelCode(channelCode);
        List<String> nickNameList = jedisClient.lrange(Constants.USER_NICK_NAME, 0, jedisClient.llen(Constants.USER_NICK_NAME));
        portalUserInfo.setNickName(getDefaultNickName(nickNameList));
        portalUserInfo.setSignature(Constants.USER_SIGNATURE);
        portalUserInfo.setUserIcon(Constants.USER_DEFAULT_ICON);
        portalUserInfoMapper.insertSelective(portalUserInfo);
        //tigase注册
        /*try {
            ConnectionConfiguration config = new ConnectionConfiguration(serverHost, serverPort);
            config.setSASLAuthenticationEnabled(false);
            config.setDebuggerEnabled(false);
            config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);

            XMPPConnection con = new XMPPConnection(config);
            con.connect();
            con.getAccountManager().createAccount(phoneNumber, password);
            con.disconnect();

        } catch (XMPPException e) {
            log.error("【同步tigase用户异常】:{}", ExceptionUtil.logExceptionStack(e));
            throw new CustomException(ResultEnum.EXPORT_USER_FAIL);
        }*/

        Map<String, String> map = new HashMap();
        map.put("userId", userId);
        map.put("accessToken", accessToken);
        return map;
    }

    /**
     * description: 获取被推荐用户信息
     * author sunny
     * createDate 2019-05-15 上午 9:41
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, Object>> findRecommendUser() throws Exception {
        return portalUserInfoMapper.findRecommendUser();
    }

    /**
     * description: 获取默认用户昵称
     * author sunny
     * createDate 2019-05-16 下午 4:05
     * @param nickNameList
     * @return
     */
    private String getDefaultNickName(List<String> nickNameList){
        String nickName = RandomUtil.getRandomNumChar(6);
        if(nickNameList.contains(nickName)){
            nickName = getDefaultNickName(nickNameList);
        }
        return nickName;
    }

}
